<template>
  <div class="pt-2 tree-panels-container">
    <n-tree
      block-line
      :data="allOptions"
      :override-default-node-click-behavior="override"
      :render-label="renderLabel"
      :on-load="handleLoad"
      :default-expanded-keys="[
        '{block:files}',
        '{block:tools}',
        '{block:fileType}'
      ]"
      :node-props="nodeProps"
      :virtual-scroll="true"
      style="max-height: 90vh"
    />
    <n-dropdown
      placement="bottom-start"
      trigger="manual"
      :x="sourceDropDown.x"
      :y="sourceDropDown.y"
      :options="sourceDropDownOptions"
      :show="sourceDropDown.showDropdown"
      :on-clickoutside="handleSourceDropClickOutside"
      @select="handleSourceDropSelect"
      :render-label="renderSourceDropDownMenu"
    />
  </div>
</template>

<script setup lang="ts">
import type { TreeOverrideNodeClickBehavior, TreeOption } from 'naive-ui'
import useUserStore from '@/stores/modules/user'
import useExplorerStore from '@/stores/modules/explorer'
import { getSourceByPage } from '@/api/source'
import { navTypeList } from '@/constants/explorer'
import { arraysIsEqual } from '@/utils'
import { renderDropLabel } from '@/utils/commonBusiness'
import { DropDownType, contextMenus } from '../constants/dropDown'
import type { IndexObj } from '@/types/commom'
import { getDepartmentByPage, getUserDepartmentByPage } from '@/api/department'
import { useSourceAuth } from '@/hooks/useSourceAuth'

const emits = defineEmits<{
  (e: 'nodeClick', item: IndexObj): void
  (e: 'menuSelect', key: string, menu: IndexObj[]): void
}>()

const userStore = useUserStore()
const explorerStore = useExplorerStore()
const { sourceAuths, loadSourceAuth } = useSourceAuth()

const override: TreeOverrideNodeClickBehavior = ({ option }) => {
  if (!option.myIcon) {
    return 'toggleExpand'
  }
  return 'default'
}

const renderLabel = (info: {
  option: TreeOption
  checked: boolean
  selected: boolean
}) => {
  // console.log('render-label')

  if (!info.option.myIcon) {
    return info.option.label
  }
  return renderDropLabel(
    info.option.myIcon as string,
    info.option.label as string
  )
}

// 位置
const positionOptions = ref<IndexObj[]>([
  {
    key: '{block:files}',
    label: '位置',
    children: [
      // {
      //   label: '收藏夹',
      //   key: '{userFav}',
      //   myIcon: 'shoucangjiashangpin',
      //   isLeaf: true,
      //   myType: navTypeList.USER_FAV
      // },
      {
        label: '个人空间',
        key: 'source',
        myIcon: 'home',
        isLeaf: false,
        myType: navTypeList.SOURCE
      },
      {
        label: '我所在的部门',
        key: '{groupRootSelf}',
        myIcon: 'bumenwenjianjia',
        isLeaf: false,
        myType: navTypeList.DEP
      },
      {
        label: '与我协作',
        key: '{shareToMe}',
        myIcon: 'folder-share',
        isLeaf: false,
        myType: navTypeList.SHARE_TO_ME
      }
    ]
  }
])

// 工具
const toolOptions = ref<IndexObj[]>([
  {
    key: '{block:tools}',
    label: '工具',
    children: [
      {
        label: '我的协作',
        key: '{userShare}',
        myIcon: 'fenxiang-copy',
        myType: navTypeList.USER_SHARE
      },
      {
        label: '外链分享',
        key: '{userShareLink}',
        myIcon: 'zhuanfa2-copy',
        myType: navTypeList.USER_SHARE_LINK
      },
      {
        label: '回收站',
        key: '{userRecycle}',
        myIcon: 'huishouzhan-copy',
        myType: navTypeList.USER_RECYCLE
      }
    ]
  }
])

// 文件类型
const fileTypeOptions = ref<IndexObj[]>([
  {
    key: '{block:fileType}',
    label: '文件类型',
    children: [
      {
        label: '文档',
        key: '{userFileType:doc}',
        myIcon: 'wendangleixingtubiao_word',
        myType: navTypeList.FILE_TYPE
      },
      {
        label: '图片',
        key: '{userFileType:image}',
        myIcon: 'tupianwenjian',
        myType: navTypeList.FILE_TYPE
      },
      {
        label: '音乐',
        key: '{userFileType:music}',
        myIcon: 'wenjianleixing-biaozhuntu-shengyinwenjian',
        myType: navTypeList.FILE_TYPE
      },
      {
        label: '视频',
        key: '{userFileType:movie}',
        myIcon: 'wenjianleixing-biaozhuntu-shipinwenjian',
        myType: navTypeList.FILE_TYPE
      },
      {
        label: '压缩包',
        key: '{userFileType:zip}',
        myIcon: 'yasuobao',
        myType: navTypeList.FILE_TYPE
      },
      {
        label: '其他',
        key: '{userFileType:others}',
        myIcon: 'wenjianleixing-biaozhuntu-weizhiwenjian',
        myType: navTypeList.FILE_TYPE
      }
    ]
  }
])

// 整体的左侧树形
const allOptions = computed(() => {
  return positionOptions.value.concat(toolOptions.value, fileTypeOptions.value)
})

const handleLoad = (node: IndexObj): Promise<void> => {
  if (node.myType === navTypeList.SOURCE) {
    // 进行文件资源的加载
    return new Promise<void>((resolve) => {
      getSourceByPage({
        parentId: node.key as string,
        isDir: 1
      })
        .then((res) => {
          node.children = res.data.items.map((item) => {
            return {
              ...item,
              isLeaf: item.hasFolder === 0 || !!item.isLeaf, // 这里需要没有子文件夹
              key: item.id,
              label: item.filename,
              myIcon: 'wenjianjia2',
              myType: navTypeList.SOURCE,
              isEdit: false
            }
          })
          resolve()
        })
        .catch(console.error)
    })
  } else if (node.myType === navTypeList.DEP) {
    // 1. 加载子部门
    // 2. 加载子文件夹

    return new Promise<void>((resolve) => {
      // 获取rootSourceId和depId
      let rootSourceId
      let depId
      if (node.key === '{groupRootSelf}') {
        rootSourceId = '-2'
        depId = '1'
      } else {
        rootSourceId =
          node.Sources && node.Sources.length ? node.Sources[0].id : '-2'
        depId = node.id
      }

      // 获取子部门和子文件夹
      Promise.all([
        getUserDepartmentByPage({
          page: 1,
          pageSize: 9999,
          pid: depId
        }),
        getSourceByPage({
          page: 1,
          pageSize: 9999,
          parentId: rootSourceId,
          isDir: 1
        })
      ])
        .then(([res1, res2]) => {
          const deps = res1.data.items.map((item) => {
            return {
              ...item,
              isLeaf: false, // 这里需要没有子文件夹
              key: item.id,
              label: item.name,
              myIcon: 'bumenwenjianjia',
              myType: navTypeList.DEP,
              isEdit: false
            }
          })

          const sources = res2.data.items.map((item) => {
            return {
              ...item,
              isLeaf: item.hasFolder === 0 || !!item.isLeaf, // 这里需要没有子文件夹
              key: item.id,
              label: item.filename,
              myIcon: 'wenjianjia2',
              myType: navTypeList.SOURCE,
              isEdit: false
            }
          })

          node.children = [...deps, ...sources]

          if (!node.children.length) {
            node.isLeaf = true
          }
          resolve()
        })
        .catch(console.error)
    })
  }

  return new Promise<void>((resolve) => {
    setTimeout(() => {
      node.isLeaf = true
      resolve()
    }, 1000)
  })
}

const nodeProps = ({ option }: { option: IndexObj }) => {
  return {
    onClick(e: MouseEvent) {
      // console.log(e.target.nodeName)

      // 防止下拉toggle图标点击导致该项被选中
      // if (e.target.nodeName !== 'DIV') {
      //   return
      // }

      if (!option.myIcon) {
        return
      }

      emits('nodeClick', {
        ...option,
        label: option.label as string,
        key: option.key as string
      })
    },
    onContextmenu(e: MouseEvent) {
      curContextMenuOption.value = option
      const showContextMenu = () => {
        e.preventDefault()
        e.stopPropagation()
        sourceDropDown.showDropdown = false
        nextTick().then(() => {
          sourceDropDown.showDropdown = true
          sourceDropDown.x = e.clientX
          sourceDropDown.y = e.clientY
        })
      }

      if (option.myType === navTypeList.SOURCE) {
        loadSourceAuth([option.key], 0)
        // TODO 获取用户对当前文档的权限，targetID为2时
        // setTimeout(()=>{})
        curRange.value = DropDownType.TREE_SOURCE
        showContextMenu()
      } else if (option.key!.startsWith('{userFileType')) {
        // 对于文件类型被右键点击
        curRange.value = DropDownType.TREE_FILE_TYPE
        showContextMenu()
      } else if (option.key === '{userShare}') {
        curRange.value = DropDownType.TREE_SHARETO
        showContextMenu()
      } else if (option.key === '{userShareLink}') {
        curRange.value = DropDownType.TREE_LINK
        showContextMenu()
      } else if (option.key === '{userRecycle}') {
        curRange.value = DropDownType.TREE_BIN
        showContextMenu()
      } else {
        return
      }
    }
  }
}

const initUserRootSourceId = () => {
  positionOptions.value[0].children[0].key = userStore.userInfo?.rootSourceId
}

// const defaultSelectKey = ref(['source'])

onMounted(async () => {
  if (!userStore.userInfo) {
    await userStore.getUserInfo()
  }
  initUserRootSourceId()

  // console.log(explorerStore.curNav)
  // defaultSelectKey.value = explorerStore.curNav?.key
  //   ? [explorerStore.curNav.key]
  //   : ['source']
})

// 文件列表右键菜单
const curRange = ref('')
// 右键点击时，选择的项目
const curContextMenuOption = ref<IndexObj>({})
const renderSourceDropDownMenu = (option: IndexObj) => {
  return renderDropLabel(option.myIcon, option.label, '#888', '15px', '#13b1fe')
}

const sourceDropDown = reactive<IndexObj>({
  showDropdown: false,
  x: 0,
  y: 0
})

// 根据当前用户的权限信息和所处不同的树形位置确定最终的下拉菜单
const sourceDropDownOptions = computed(() => {
  let baseMenu: IndexObj[] = []

  if (userStore.userInfo) {
    baseMenu = contextMenus.filter((item) => {
      let res = true
      if (item.auth) {
        if (item.auth.role) {
          // 检查系统权限
          res =
            userStore.userInfo?.role.Permissions.some((v) => {
              return item.auth.role?.includes(v.ename)
            }) || false
          if (!res) {
            return res
          }
        }
        if (item.auth.doc) {
          // 检查文档权限
          res = sourceAuths.value.some((v) => {
            return item.auth.doc.includes(v)
          })

          if (!res) {
            return res
          }
        }

        if (item.auth.other && item.auth.other.length) {
          // 检查其他
          // 检查需要剪切板
          if (item.auth.other.includes('cut-exist')) {
            res = explorerStore.cutSourceList.length > 0
            if (!res) {
              return res
            }
          }
        }
      }
      if (item.range) {
        res = item.range.includes(curRange.value)
      }
      return res
    })
  } else {
    baseMenu = contextMenus.filter((item) => {
      if (item.auth) {
        return false
      } else {
        if (item.range) {
          return item.range.includes(curRange.value)
        } else {
          return true
        }
      }
    })
  }

  return baseMenu.filter((item) => {
    // 处理分割线
    if (item.type === 'divider' && item.needKey) {
      const keys = baseMenu
        .filter((item) => item.type !== 'divider')
        .map((v) => v.key)

      if (arraysIsEqual(keys, item.needKey)) {
        return false
      }
      return baseMenu.some((v) => item.needKey.includes(v.key))
    } else {
      return true
    }
  })
})

const handleSourceDropClickOutside = () => {
  sourceDropDown.showDropdown = false
}

// 右键菜单项被选择
const handleSourceDropSelect = (key: string) => {
  // console.log(key, 'key')
  sourceDropDown.showDropdown = false
  if (key === 'reflesh-tree') {
    // 刷新树目录，进行文件节点的加载
    handleLoad(curContextMenuOption.value)
  } else if (key === 'createDir') {
    // handleToCreateDir()
  } else if (key.startsWith('new.')) {
    // handleToCreateFile(key)
  } else {
    emits('menuSelect', key, [curContextMenuOption.value])
  }
  // 部分类型需要给父亲处理，传递给父组件一个node即可
}
</script>

<style scoped lang="scss">
.tree-panels-container {
  :deep(.n-tree .n-tree-node) {
    height: 30px;
    align-items: center;
  }

  :deep(.n-tree-node-wrapper) {
    padding: 0;
  }
}
</style>
